home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / recio212.zip / rgett.c < prev    next >
C/C++ Source or Header  |  1995-01-29  |  11KB  |  295 lines

  1. /*****************************************************************************
  2.    MODULE: rgett.c
  3.   PURPOSE: recio character delimited time input functions
  4. COPYRIGHT: (C) 1994-1995, William Pierpoint
  5.  COMPILER: Borland C Version 3.1
  6.        OS: MSDOS Version 6.2
  7.   VERSION: 2.12
  8.   RELEASE: January 29, 1995
  9. *****************************************************************************/
  10.  
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <time.h>
  17.  
  18. #include "recio.h"
  19.  
  20. extern int _risready(REC *rp, int mode);
  21. extern char *_rfldstr(REC *rp, size_t len);
  22. extern char *_rerrs(REC *rp, int errnum);
  23.  
  24. #define rtmfmt(rp) ((rp)->r_tmfmt)
  25.  
  26. int _rgett_c_warno;  /* warning number */
  27.  
  28. /****************************************************************************/
  29. static int                   /* return number of digits read                */
  30.     istrncpy(                /* copy up to n digits from src to dst         */
  31.               char *dst,     /* destination string                          */
  32.         const char *src,     /* source string                               */
  33.                 int n)       /* number of digits to copy                    */
  34. /****************************************************************************/
  35. {
  36.     int i;
  37.     
  38.     /* copy up to n digits */
  39.     for (i=0; i < n; i++) {
  40.         if (isdigit(*src)) {
  41.             *dst++ = *src++;
  42.         } else {
  43.             break;
  44.         }
  45.     }
  46.     *dst = '\0';
  47.     return i;
  48. }
  49.  
  50. /****************************************************************************/
  51. void                         /* returns nothing                             */
  52.     _tminit(                 /* initialize a tm struct                      */
  53.         struct tm *t)        /* tm struct                                   */
  54. /****************************************************************************/
  55. {
  56.     t->tm_sec = 0;
  57.     t->tm_min = 0;
  58.     t->tm_hour = 0;
  59.     t->tm_mday = 1;
  60.     t->tm_mon = 0;
  61.     t->tm_year = 70;
  62.     t->tm_isdst = -1;
  63. }
  64.  
  65. /****************************************************************************/
  66. struct tm                    /* return tm                                   */
  67.     timetotm(                /* convert time_t to struct tm                 */
  68.         time_t time)         /* source time                                 */
  69. /****************************************************************************/
  70. {
  71.     struct tm t;
  72.     
  73.     if (time == (time_t)-1) _tminit(&t);
  74.     else memcpy(&t, localtime(&time), sizeof(struct tm));
  75.     return t;
  76. }
  77.  
  78. /****************************************************************************/
  79. time_t                       /* return time (-1=error)                      */
  80.     tmtotime(                /* convert struct tm to time_t                 */
  81.         struct tm t)         /* broken-down time source                     */
  82. /****************************************************************************/
  83. {
  84.     time_t time;             /* return time (-1 = error)    */
  85.     
  86.     /* note: see section 3.5 of design.txt for mktime range */
  87.     time = mktime(&t);
  88.     if (time == (time_t) -1) errno = ERANGE;
  89.     return time;
  90. }
  91.  
  92. /****************************************************************************/
  93. time_t                       /* return time (-1=error)                      */
  94.     sftotime(                /* convert formated string to time_t           */
  95.         const char *s,       /* source string with time data                */
  96.         const char *fmt)     /* time format                                 */
  97. /****************************************************************************/
  98. {
  99.     time_t time=(time_t) -1; /* return time (-1=error) */
  100.     struct tm t;             /* broken-down time */
  101.  
  102.     t = sftotm(s, fmt);
  103.     if (!errno) time = tmtotime(t);
  104.     return time;
  105. }
  106.  
  107. /****************************************************************************/
  108. struct tm                    /* return tm (if error, errno != 0)            */
  109.     sftotm(                  /* convert formated string to tm               */
  110.         const char *s,       /* source string with time data                */
  111.         const char *fmt)     /* time format                                 */
  112. /****************************************************************************/
  113. {
  114.     struct tm t;     /* tm struct for time */
  115.     char buf[5];     /* string buffer */
  116.  
  117.     errno = 0;
  118.     _rgett_c_warno = 0;
  119.     _tminit(&t);
  120.     for ( ; ; fmt++) {
  121.             /* skip white space */
  122.             while (isspace(*s)) s++;
  123.             while (isspace(*fmt)) fmt++;
  124.             if (!*s || !*fmt) break;
  125.  
  126.             if (*fmt == '%') {
  127.             switch (*++fmt) {
  128.             case 'm':  /* month (0 to 11) */
  129.                 s += istrncpy(buf, s, 2);
  130.                 if (*buf) {
  131.                     t.tm_mon = atoi(buf) - 1;
  132.                     if (t.tm_mon < 0 || t.tm_mon > 11) {
  133.                         /* error */
  134.                         errno = EINVDAT;
  135.                         goto done;
  136.                      }
  137.                 }
  138.                 break;
  139.             case 'd':  /* day of month (1 to 31) */
  140.                 s += istrncpy(buf, s, 2);
  141.                 if (*buf) {
  142.                     t.tm_mday = atoi(buf);
  143.                     if (t.tm_mday < 1 || t.tm_mday > 31) {
  144.                         /* error */
  145.                         errno = EINVDAT;
  146.                         goto done;
  147.                     }
  148.                 }
  149.                 break;
  150.             case 'y':  /* 2-digit year (1970 to 2069) */
  151.                 s += istrncpy(buf, s, 2);
  152.                 if (*buf) {
  153.                     t.tm_year = atoi(buf);
  154.                     if (t.tm_year < 70) t.tm_year += 100;
  155.                 }
  156.                 break;
  157.             case 'Y':  /* 4-digit year */
  158.                 s += istrncpy(buf, s, 4);
  159.                 if (*buf) {
  160.                     t.tm_year = atoi(buf) - 1900;
  161.                 }
  162.                 break;
  163.             case 'H':  /* hour (0 to 23) */
  164.                 s += istrncpy(buf, s, 2);
  165.                 if (*buf) {
  166.                     t.tm_hour = atoi(buf);
  167.                     if (t.tm_hour > 23) {
  168.                         /* error */
  169.                         errno = EINVDAT;
  170.                         goto done;
  171.                     }
  172.                 }
  173.                 break;
  174.             case 'M':  /* minute (0 to 59) */
  175.                 s += istrncpy(buf, s, 2);
  176.                 if (*buf) {
  177.                     t.tm_min = atoi(buf);
  178.                     if (t.tm_min > 59) {
  179.                         /* error */
  180.                         errno = EINVDAT;
  181.                         goto done;
  182.                     }
  183.                 }
  184.                 break;
  185.             case 'S':  /* second (0 to 61) */
  186.                        /* includes up to two leap seconds */
  187.                 s += istrncpy(buf, s, 2);
  188.                 if (*buf) {
  189.                     t.tm_sec = atoi(buf);
  190.                     if (t.tm_sec > 61) {
  191.                         /* error */
  192.                         errno = EINVDAT;
  193.                         goto done;
  194.                     }
  195.                 }
  196.                 break;
  197.             case '%':  /* literal % */
  198.                 if (*s=='%') {
  199.                     s++;
  200.                 } else {
  201.                     /* error */
  202.                     errno = EINVDAT;
  203.                     goto done;
  204.                 }
  205.                 break;
  206.             default:
  207.                 /* error */
  208.                 errno = EINVAL;
  209.                 goto done;
  210.             }
  211.         } else {
  212.             if (*s==*fmt) {
  213.                 s++;
  214.                 continue;
  215.             } else if (isspace(*fmt)) {
  216.                 continue;
  217.             } else {
  218.                 /* error */
  219.                 errno = EINVDAT;
  220.                 goto done;
  221.             }
  222.         }
  223.     }
  224. done:
  225.     if (!errno) {
  226.         /* warning if any non-whitespace part of format string left */
  227.         while (isspace(*fmt)) fmt++;
  228.         if (*fmt) _rgett_c_warno = R_WTMFMT;
  229.     }
  230.     return t;
  231. }
  232.  
  233. /****************************************************************************/
  234. struct tm                    /* return tm                                   */
  235.     rgettm(                  /* get time from record stream                 */
  236.         REC *rp)             /* record pointer                              */
  237. /****************************************************************************/
  238. {
  239.     struct tm t;             /* return tm */
  240.     struct tm val;           /* conversion value         */
  241.     char *fldptr;            /* pointer to field buffer  */
  242.  
  243.     _tminit(&t);
  244.     if (_risready(rp, R_READ)) {
  245.         fldptr = _rfldstr(rp, 0);
  246.         if (fldptr) {
  247.             strims(fldptr);
  248.             for (;;) {
  249.                 if (*fldptr != '\0') {
  250.                     val = sftotm(fldptr, rtmfmt(rp));
  251.                     if (errno) {
  252.                         switch (errno) {
  253.                         case ERANGE:
  254.                             fldptr = _rerrs(rp, R_ERANGE);
  255.                             break;
  256.                         case EINVAL:
  257.                             fldptr = _rerrs(rp, R_EINVAL);
  258.                             break;
  259.                         case EINVDAT:
  260.                             fldptr = _rerrs(rp, R_EINVDAT);
  261.                             break;
  262.                         }
  263.                         if (fldptr) { continue; } else { goto done; } 
  264.                     } else {
  265.                         t = val;
  266.                         if (_rgett_c_warno) rsetwarn(rp, _rgett_c_warno);
  267.                         goto done;
  268.                     }
  269.                 } /* missing data */ 
  270.                 fldptr = _rerrs(rp, R_EMISDAT); 
  271.                 if (fldptr) { continue; } else { goto done; }
  272.             }
  273.         } 
  274.     }
  275. done:
  276.     return t;
  277. }
  278.  
  279. /****************************************************************************/
  280. time_t                       /* return time (-1=error)                      */
  281.     rgett(                   /* get time from record stream                 */
  282.         REC *rp)             /* record pointer                              */
  283. /****************************************************************************/
  284. {
  285.     time_t time=(time_t) -1; /* return time (-1 = error) */
  286.     struct tm t;
  287.  
  288.     t = rgettm(rp);
  289.     if (_risready(rp, R_READ)) {
  290.         time = tmtotime(t);
  291.         if (time == (time_t) -1) rseterr(rp, R_ERANGE);
  292.     }
  293.     return time;
  294. }
  295.